package com.ufox.controller;


import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ufox.entity.*;
import com.ufox.req.PasswordREQ;
import com.ufox.req.StaffREQ;
import com.ufox.service.IStaffService;
import com.ufox.utils.JWTUtil;
import com.ufox.utils.MD5Util;
import com.ufox.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.*;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * <p>
 * 员工信息表 前端控制器
 * </p>
 *
 * @author 优狐科技-www.hbufox.com
 * @since 2022-05-31
 */
@Slf4j
@RestController
@RequestMapping("/staff")
public class StaffController {

    @Autowired
    private IStaffService staffService;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("login")
    public Result login(@RequestBody StaffREQ staff) {

        //log.info(username+"---"+password);

        //1 获取id
        String id = staff.getId();
        if (StrUtil.isBlank(id)) {
            return Result.error("验证码错误");
        }

        String code = staff.getCode();
        if (StrUtil.isBlank(code)) {
            return Result.error("请输入验证码");
        }

        //2 根据id 查询
        String uuid = (String) redisUtils.get(id);
        if (!code.equals(uuid)) {
            return Result.error("验证码错误");
        }

        //3 判断

        LambdaQueryWrapper<Staff> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Staff::getUsername, staff.getUsername());

        String passWord = MD5Util.getMD5String(staff.getPassword());
        wrapper.eq(Staff::getPassword, passWord);

        Staff s = staffService.getOne(wrapper);
        if (s == null) {
            return Result.error("用户名或密码错误");
        } else {
//            String token = s.getId() + "@" + UUID.randomUUID().toString().replace("-", "");
//            return Result.ok(token);
            HashMap<String, Object> map = new HashMap<>();
            map.put("id", s.getId());
            String token = JWTUtil.getJWT(map);
            System.out.println(token);
            return Result.ok(token);
        }
    }

    @GetMapping("/info/{token}")
    public Result info(@PathVariable String token) {

//        int index = token.indexOf("@");
//        String id = token.substring(0, index);
        log.info(token);

        DecodedJWT jwt = JWTUtil.verify(token);
        String id = jwt.getClaim("id").asString();


        //判断 redis数据中有没有登录用户的id 相同,

        //获取到了所有 以Bearer  开头的键
        Set<String> keys = redisTemplate.keys("Bearer *");
        for (String key : keys) {

            //截取掉Bearer
            key = key.substring(7);

            //从token中获取id
            DecodedJWT verify = JWTUtil.verify(key);
            String tokenId = verify.getClaim("id").asString();

            if (id.equals(tokenId)) {
                //把之前登录用户的token删除
                redisUtils.del("Bearer " + key);
                break;
            }
        }

        Staff staff = staffService.getById(id);
        if (staff == null) {
            return Result.error("获取用户失败");
        } else {
            //登录成功以后,后台也保存用户的登录状态
            String ss = JSONUtil.toJsonStr(staff);
            redisUtils.set("Bearer " + token, ss, 3600);
            return Result.ok(staff);
        }
    }


    /**
     * 退出
     *
     * @return
     */
    @PostMapping("/logout")
    public Result logout(HttpServletRequest request) {
        //根据 id  token 从数据库删除数据
        //获取请求头中token
        String token = request.getHeader("Authorization");
        redisUtils.del(token);
        return Result.ok();
    }

    @PostMapping("/username")
    protected Result findByUserName(@RequestBody Staff staff) {
        System.out.println(staff.getId());
        LambdaQueryWrapper<Staff> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(staff.getUsername()), Staff::getUsername, staff.getUsername());
        List<Staff> list = staffService.list(wrapper);
        Result result = Result.ok();

        if (list.size() > 0 && staff.getId() == null) {
            result.setFlag(false);
        } else {
            result.setFlag(true);
        }
        return result;
    }


    /**
     * 校验原密码是否正确
     *
     * @return
     */
    @PostMapping("/pwd")
    public Result checkPassword(@RequestBody PasswordREQ req) {
        return staffService.checkPassword(req);
    }


    /**
     * 修改密码
     *
     * @return
     */
    @PutMapping("/pwd")
    public Result updatePassword(@RequestBody PasswordREQ req) {
        return staffService.updatePassword(req);
    }


    @GetMapping("/id/{id}")
    protected Result selectById(@PathVariable Integer id) {
        Staff staff = staffService.getById(id);
        return Result.ok(staff);
    }


    //分页 查询
    @PostMapping("/{page}/{size}")
    public Result findAllCond(@PathVariable int page, @PathVariable int size, @RequestBody StaffCond staffCond) {
        Page<Staff> pageInfo = new Page<>(page, size);
        LambdaQueryWrapper<Staff> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(staffCond.getUsername()), Staff::getUsername, staffCond.getUsername());
        wrapper.like(StringUtils.isNotBlank(staffCond.getName()), Staff::getName, staffCond.getName());
        Page<Staff> list = staffService.page(pageInfo, wrapper);
        return Result.ok(list);
    }

    //添加  或 修改
    @PostMapping
    public Result saveOrUpdateSupplier(@RequestBody Staff staff) {


        if (staff.getId() == null) {
            String password = staff.getPassword();
            staff.setPassword(MD5Util.getMD5String(password));
        }

        boolean b = staffService.saveOrUpdate(staff);
        return (b ? Result.ok() : Result.error(""));

    }

    //删除
    @DeleteMapping("/{id}")
    public Result delStaff(@PathVariable Integer id) {
        boolean b = staffService.removeById(id);
        return (b ? Result.ok() : Result.error(""));
    }

    //批量删除
    @PostMapping("/batch")
    public Result delStaffsBatch(@RequestBody List<Integer> ids) {
        boolean b = staffService.removeByIds(ids);
        return (b ? Result.ok() : Result.error(""));
    }
}

